package com.lovezy.platform.wiki.service.impl;

import com.lovezy.platform.core.base.enums.StatusEnum;
import com.lovezy.platform.core.base.query.Pager;
import com.lovezy.platform.core.base.service.MapperService;
import com.lovezy.platform.wiki.exception.WikiException;
import com.lovezy.platform.wiki.exception.WikiExceptionEnum;
import com.lovezy.platform.wiki.form.FollowForm;
import com.lovezy.platform.wiki.mapper.GameFollowMapper;
import com.lovezy.platform.wiki.model.GameFollow;
import com.lovezy.platform.wiki.model.GameFollowExample;
import com.lovezy.platform.wiki.service.GameFollowService;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Optional;

/**
 * 百科关注服务实现
 * Created by jin on 2017/12/3.
 */
@Service
public class GameFollowServiceImpl extends MapperService<GameFollow,Integer,GameFollowMapper> implements GameFollowService{

    private final Object FOLLOW_OBJ = new Object();


    @Override
    public GameFollow follow(FollowForm form) {
        String mid = form.getMemberId();
        Integer gameId = form.getId();
        checkGameHasFollowed(gameId, mid);

        synchronized (FOLLOW_OBJ) {
            checkGameHasFollowed(gameId, mid);
            return doFollowGame(gameId, mid);
        }
    }

    @Override
    public void unFollow(FollowForm form) {
        String mid = form.getMemberId();
        Integer gameId = form.getId();
        GameFollow follow = findFollowedGame(gameId, mid);
        GameFollow update = new GameFollow();
        update.setFollowId(follow.getFollowId());
        follow.setStatus(StatusEnum.DELETED.value());
        mapper.updateByPrimaryKeySelective(follow);
    }

    @Override
    public boolean isFollowed(FollowForm followForm) {
        String mid = followForm.getMemberId();
        Integer gameId = followForm.getId();
        GameFollowExample example = new GameFollowExample();
        example.createCriteria()
                .andMemberIdEqualTo(mid)
                .andGameIdEqualTo(gameId)
                .andStatusEqualTo(StatusEnum.NORMAL.value());
        return mapper.countByExample(example) > 0;
    }

    private GameFollow doFollowGame(Integer gameId, String mid) {
        Date now = new Date();
        GameFollow follow = new GameFollow();
        follow.setGameId(gameId);
        follow.setMemberId(mid);
        follow.setStatus(StatusEnum.NORMAL.value());
        follow.setGmtCreate(now);
        follow.setGmtModify(now);
        mapper.insert(follow);
        return follow;
    }

    private GameFollow findFollowedGame(Integer gameId, String mid) {
        Optional<GameFollow> followOptional = findMemberFollowedGame(gameId, mid);
        return followOptional.orElseThrow(() -> new WikiException(WikiExceptionEnum.WIKI_HAS_NOT_FOLLOWED));
    }

    private void checkGameHasFollowed(Integer gameId, String mid) {
        Optional<GameFollow> followOptional = findMemberFollowedGame(gameId, mid);
        if (followOptional.isPresent()) {
            throw new WikiException(WikiExceptionEnum.WIKI_HAS_FOLLOWED);
        }
    }

    private Optional<GameFollow> findMemberFollowedGame(Integer gameId, String mid) {
        GameFollowExample example = new GameFollowExample();
        example.createCriteria()
                .andGameIdEqualTo(gameId)
                .andMemberIdEqualTo(mid)
                .andStatusEqualTo(StatusEnum.NORMAL.value());
        return Pager.doSingleton(() -> mapper.selectByExample(example));
    }


}
